package com.audaque.springboot.foshanupload.web.esdatademo.controller;


import cn.hutool.core.bean.BeanUtil;
import com.audaque.springboot.foshanupload.core.result.R;
import com.audaque.springboot.foshanupload.web.esdatademo.model.pojo.Country;
import com.audaque.springboot.foshanupload.web.esdatademo.model.req.CountryParam;
import com.audaque.springboot.foshanupload.web.esdatademo.repository.CountryRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author zhongguobin
 * @date 2024-03-24 15:56
 * @description TODO
 */
@Validated
@Slf4j
@RestController

@Tag(name = "国家 前端控制器")

@RequestMapping("/country")
public class MixController {

    @Autowired
    private CountryRepository countryRepository;
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private RestHighLevelClient restHighLevelClient;



    @PostMapping(value = "/create")
    @Operation(summary = "国家 创建")
    public R<String> create(@RequestBody Country params) throws Exception {
        IndexRequest request = new IndexRequest("utour_countries");
        if (StringUtils.isNotBlank(params.get_id())) {
            throw new Exception("创建时不能填_id");
        }
        Map<String, Object> map = BeanUtil.beanToMap(params, false, true);
        request.source(map, XContentType.JSON);
        // 手动将缓存区中的数据刷新到磁盘中，但是会影响性能
        request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        // 同步
        IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        if (response.status() != RestStatus.OK) {
            throw new Exception("创建失败");
        }
        return R.ok("创建成功");
    }


    @PostMapping(value = "/update")
    @Operation(summary = "国家 更新(部分)")
    public R<String> update(@RequestBody Country params) throws Exception {
        if (StringUtils.isBlank(params.get_id())) {
            throw new Exception("更新时_id必填");
        }
        UpdateRequest request = new UpdateRequest("utour_countries", params.get_id());

        Country country = countryRepository.findBy_id(params.get_id());
        if(country==null){
            throw new Exception("更新时原数据不存在");
        }
        BeanUtil.copyProperties(params, country);
        // 通过Map更新
        country.set_id(null);
        Map<String, Object> docMap = BeanUtil.beanToMap(country, false, true);
        request.doc(docMap);
        // 手动将缓存区中的数据刷新到磁盘中，但是会影响性能
        request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
        if (response.status() != RestStatus.OK) {
            throw new Exception("更新失败");
        }
        return R.ok("更新成功");
    }
    @PostMapping(value = "/delete/{countryId}")
    @Operation(summary = "国家 删除")
    public R<String> delete(@PathVariable("countryId") String countryId) throws Exception {
        countryRepository.deleteById(countryId);
        return R.ok("删除成功");
    }


    @PostMapping(value = "/deleteByQuery/{countryId}")
    @Operation(summary = "国家 删除(多个)")
    public R<String> deleteByQuery(@PathVariable("countryId") String countryId) throws Exception {
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("id", countryId))
                .build();
        elasticsearchRestTemplate.delete(nativeSearchQuery, Country.class, IndexCoordinates.of("utour_countries"));
        return R.ok("删除成功");
    }


    @PostMapping(value = "/page")
    @Operation(summary = "国家 分页查询（页码从0开始）")
    public R<Page<Country>> page(@RequestBody CountryParam req) {
        if (req.getId() != null) {
            Country country = countryRepository.findById(req.getId());
            List<Country> countries = new ArrayList<>();
            countries.add(country);
            PageImpl pageImpl = new PageImpl(countries, PageRequest.of(0, 1), 1);
            return R.ok(pageImpl);
        }

        PageRequest pageRequest = PageRequest.of(Integer.parseInt(Long.toString(req.getPageNum())), Integer.parseInt(Long.toString(req.getPageSize())));
        Page<Country> page = countryRepository.findAll(pageRequest);
        return R.ok(page);
    }


    @GetMapping(value = "/list")
    @Operation(summary = "国家 列表查询")
    public R<List<Country>> list(@RequestParam String keyword) {
        return R.ok(countryRepository.findByCnOrNameOrCodeOrPyOrPy1OrZhHant(keyword, keyword, keyword, keyword, keyword, keyword));
    }


    @GetMapping(value = "/detail/{countryId}")
    @Operation(summary = "国家 单体查询")
    public R<Country> detail(@PathVariable("countryId") Long countryId) {
        Country one = countryRepository.findById(countryId);
        return R.ok(one);
    }


}
